#!/usr/bin/env python3
"""
Ford Focus交互式逆向分析
尝试点击页面元素寻找规格说明信息
"""

import sys
import os
import json
import time
from datetime import datetime

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from src.base import BaseWebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains

class InteractiveFocusAnalyzer:
    """Ford Focus交互式分析器"""
    
    def __init__(self):
        self.driver_manager = BaseWebDriver()
        self.driver = None
        self.wait = None
        self.results = {
            "analysis_date": datetime.now().isoformat(),
            "target_url": "",
            "discovered_models": [],
            "interaction_results": [],
            "api_discoveries": [],
            "errors": []
        }
    
    def setup_and_navigate(self):
        """初始化并导航到页面"""
        try:
            self.driver_manager.setup_driver()
            self.driver = self.driver_manager.driver
            if not self.driver:
                raise Exception("驱动初始化失败")
            
            self.wait = WebDriverWait(self.driver, 15)
            
            with open('fetchNgc2.json', 'r', encoding='utf-8') as f:
                config = json.load(f)
            url0 = config['sub_model']['url0']
            
            print(f"🌐 正在访问: {url0}")
            self.results["target_url"] = url0
            
            self.driver.get(url0)
            time.sleep(5)
            
            self.handle_cookies()
            print(f"✅ 页面加载成功")
            return True
            
        except Exception as e:
            error_msg = f"初始化失败: {e}"
            print(f"❌ {error_msg}")
            self.results["errors"].append(error_msg)
            return False
    
    def handle_cookies(self):
        """处理Cookie弹窗"""
        try:
            if not self.driver:
                return
                
            time.sleep(3)
            cookie_selectors = [
                "#onetrust-accept-btn-handler",
                "button[id*='accept']",
                "button[class*='accept']",
                ".ot-accept-all-handler"
            ]
            
            for selector in cookie_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for element in elements:
                        if element.is_displayed():
                            self.driver.execute_script("arguments[0].click();", element)
                            print(f"✅ 处理了Cookie弹窗")
                            time.sleep(2)
                            return
                except:
                    continue
        except Exception as e:
            print(f"⚠️ Cookie处理异常: {e}")
    
    def discover_focus_models(self):
        """发现Focus车型信息"""
        try:
            print("\n🚗 发现Focus车型...")
            
            # 查找车型卡片
            model_selectors = [
                "div[class*='card']",
                "div[class*='tile']",
                "div[class*='product']",
                ".model-card",
                ".variant-card"
            ]
            
            models = []
            
            # 滚动到不同位置寻找车型
            scroll_positions = [0, 1000, 2000, 3000]
            
            for pos in scroll_positions:
                self.driver.execute_script(f"window.scrollTo(0, {pos});")
                time.sleep(2)
                
                # 查找Focus相关的标题
                focus_headers = self.driver.find_elements(By.XPATH, "//h3[contains(text(), 'Focus')]")
                
                for header in focus_headers:
                    try:
                        if header.is_displayed():
                            model_name = header.text.strip()
                            
                            # 尝试找到相关的父容器
                            parent = header.find_element(By.XPATH, "./../..")
                            
                            # 在父容器中查找按钮和链接
                            buttons = parent.find_elements(By.TAG_NAME, "button")
                            links = parent.find_elements(By.TAG_NAME, "a")
                            
                            model_info = {
                                "name": model_name,
                                "header_location": header.location,
                                "buttons": [],
                                "links": []
                            }
                            
                            for button in buttons:
                                if button.is_displayed():
                                    model_info["buttons"].append({
                                        "text": button.text.strip(),
                                        "class": button.get_attribute("class"),
                                        "onclick": button.get_attribute("onclick")
                                    })
                            
                            for link in links:
                                if link.is_displayed():
                                    model_info["links"].append({
                                        "text": link.text.strip(),
                                        "href": link.get_attribute("href"),
                                        "class": link.get_attribute("class")
                                    })
                            
                            models.append(model_info)
                            
                    except Exception as e:
                        continue
            
            # 去重
            unique_models = []
            seen_names = set()
            for model in models:
                if model["name"] not in seen_names:
                    seen_names.add(model["name"])
                    unique_models.append(model)
            
            self.results["discovered_models"] = unique_models
            
            print(f"✅ 发现 {len(unique_models)} 个Focus车型:")
            for model in unique_models:
                print(f"  - {model['name']}")
                if model['buttons']:
                    print(f"    按钮: {[b['text'] for b in model['buttons'] if b['text']]}")
                if model['links']:
                    print(f"    链接: {[l['text'] for l in model['links'] if l['text']]}")
            
            return unique_models
            
        except Exception as e:
            error_msg = f"发现车型失败: {e}"
            print(f"❌ {error_msg}")
            self.results["errors"].append(error_msg)
            return []
    
    def interact_with_models(self, models):
        """与车型元素交互"""
        try:
            print("\n🔄 开始与车型元素交互...")
            
            for model in models:
                print(f"\n  🚗 分析车型: {model['name']}")
                
                try:
                    # 滚动到车型位置
                    header_y = model['header_location']['y']
                    self.driver.execute_script(f"window.scrollTo(0, {header_y - 200});")
                    time.sleep(2)
                    
                    # 重新找到该车型的标题元素
                    headers = self.driver.find_elements(By.XPATH, f"//h3[contains(text(), '{model['name']}')]")
                    
                    if headers:
                        header = headers[0]
                        parent = header.find_element(By.XPATH, "./../..")
                        
                        # 尝试悬停激活隐藏元素
                        actions = ActionChains(self.driver)
                        actions.move_to_element(parent).perform()
                        time.sleep(2)
                        
                        # 重新检查是否有新出现的按钮
                        new_buttons = parent.find_elements(By.TAG_NAME, "button")
                        new_links = parent.find_elements(By.TAG_NAME, "a")
                        
                        interaction_result = {
                            "model_name": model['name'],
                            "hover_revealed": [],
                            "clickable_elements": [],
                            "attempted_clicks": []
                        }
                        
                        # 检查悬停后新出现的元素
                        for button in new_buttons:
                            if button.is_displayed():
                                text = button.text.strip()
                                if text and text not in [b['text'] for b in model['buttons']]:
                                    interaction_result["hover_revealed"].append({
                                        "type": "button",
                                        "text": text,
                                        "class": button.get_attribute("class")
                                    })
                        
                        # 尝试点击有意义的按钮
                        target_keywords = ['learn', 'more', 'view', 'see', 'detail', 'spec', 'configure', 'build']
                        
                        for button in new_buttons + new_links:
                            if button.is_displayed():
                                text = button.text.strip().lower()
                                
                                if any(keyword in text for keyword in target_keywords) and text:
                                    try:
                                        print(f"    🔄 尝试点击: {button.text.strip()}")
                                        
                                        # 记录点击前的URL
                                        original_url = self.driver.current_url
                                        
                                        # 点击元素
                                        self.driver.execute_script("arguments[0].click();", button)
                                        time.sleep(3)
                                        
                                        # 检查点击后的变化
                                        new_url = self.driver.current_url
                                        new_title = self.driver.title
                                        
                                        click_result = {
                                            "button_text": button.text.strip(),
                                            "original_url": original_url,
                                            "new_url": new_url,
                                            "new_title": new_title,
                                            "url_changed": new_url != original_url
                                        }
                                        
                                        interaction_result["attempted_clicks"].append(click_result)
                                        
                                        if new_url != original_url:
                                            print(f"      ✅ 页面跳转到: {new_url}")
                                            
                                            # 在新页面中寻找规格信息
                                            self.analyze_new_page(model['name'], new_url)
                                            
                                            # 返回原页面
                                            self.driver.back()
                                            time.sleep(3)
                                            self.handle_cookies()
                                        
                                    except Exception as e:
                                        print(f"      ❌ 点击失败: {e}")
                                        continue
                        
                        self.results["interaction_results"].append(interaction_result)
                        
                except Exception as e:
                    print(f"    ❌ 交互失败: {e}")
                    continue
            
        except Exception as e:
            error_msg = f"交互失败: {e}"
            print(f"❌ {error_msg}")
            self.results["errors"].append(error_msg)
    
    def analyze_new_page(self, model_name, url):
        """分析跳转后的新页面"""
        try:
            print(f"      🔍 分析新页面: {url}")
            
            time.sleep(3)
            
            # 查找规格相关的内容
            spec_keywords = ['specification', 'specs', 'technical', 'features', 'engine', 'dimensions']
            
            page_analysis = {
                "model_name": model_name,
                "url": url,
                "title": self.driver.title,
                "spec_elements_found": [],
                "has_configurator": False,
                "api_calls_detected": []
            }
            
            # 检查是否进入了配置器页面
            if 'build' in url.lower() or 'configure' in url.lower() or 'ngc2' in url.lower():
                page_analysis["has_configurator"] = True
                print(f"        ✅ 检测到配置器页面！")
                
                # 在配置器页面寻找API调用
                self.monitor_configurator_apis(page_analysis)
            
            # 寻找规格相关的元素
            for keyword in spec_keywords:
                try:
                    elements = self.driver.find_elements(By.XPATH, f"//*[contains(text(), '{keyword}')]")
                    for element in elements[:3]:  # 只检查前3个
                        if element.is_displayed():
                            page_analysis["spec_elements_found"].append({
                                "keyword": keyword,
                                "text": element.text.strip()[:100],
                                "tag": element.tag_name
                            })
                except:
                    continue
            
            self.results["api_discoveries"].append(page_analysis)
            
            print(f"        📋 规格元素: {len(page_analysis['spec_elements_found'])} 个")
            
        except Exception as e:
            print(f"        ❌ 新页面分析失败: {e}")
    
    def monitor_configurator_apis(self, page_analysis):
        """监控配置器页面的API调用"""
        try:
            print(f"        🕵️ 监控配置器API...")
            
            # 检查页面脚本中的API端点
            scripts = self.driver.find_elements(By.TAG_NAME, "script")
            
            api_patterns = [
                'servicescache.ford.com',
                '/api/vehicle',
                '/api/model',
                'keyFeatures',
                'specification'
            ]
            
            for script in scripts[:10]:
                try:
                    script_content = script.get_attribute('innerHTML') or ''
                    script_src = script.get_attribute('src') or ''
                    
                    for pattern in api_patterns:
                        if pattern in script_content or pattern in script_src:
                            page_analysis["api_calls_detected"].append({
                                "pattern": pattern,
                                "source": "script_content" if pattern in script_content else "script_src",
                                "snippet": (script_content or script_src)[:200]
                            })
                            
                except Exception as e:
                    continue
            
            print(f"        📡 检测到 {len(page_analysis['api_calls_detected'])} 个API调用")
            
        except Exception as e:
            print(f"        ❌ API监控失败: {e}")
    
    def save_results(self):
        """保存交互分析结果"""
        try:
            output_file = "./release/focus_interactive_analysis.json"
            os.makedirs(os.path.dirname(output_file), exist_ok=True)
            
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(self.results, f, ensure_ascii=False, indent=2)
            
            print(f"💾 交互分析结果已保存到: {output_file}")
            
        except Exception as e:
            print(f"❌ 保存结果失败: {e}")
    
    def cleanup(self):
        """清理资源"""
        try:
            if self.driver:
                self.driver_manager.cleanup()
        except Exception as e:
            print(f"⚠️ 清理资源时出错: {e}")
    
    def run_interactive_analysis(self):
        """运行交互式分析"""
        try:
            print("🎮 开始Ford Focus交互式逆向分析...")
            print("=" * 60)
            
            if not self.setup_and_navigate():
                return False
            
            # 1. 发现车型
            models = self.discover_focus_models()
            
            if not models:
                print("❌ 未发现任何车型")
                return False
            
            # 2. 与车型交互
            self.interact_with_models(models)
            
            # 3. 保存结果
            self.save_results()
            
            print("\n🎉 交互式分析完成！")
            return True
            
        except Exception as e:
            error_msg = f"交互式分析失败: {e}"
            print(f"❌ {error_msg}")
            self.results["errors"].append(error_msg)
            return False
        
        finally:
            self.cleanup()

def main():
    """主函数"""
    analyzer = InteractiveFocusAnalyzer()
    success = analyzer.run_interactive_analysis()
    
    if success:
        print("\n📊 交互式分析结果摘要:")
        print(f"  🚗 发现车型: {len(analyzer.results['discovered_models'])} 个")
        print(f"  🔄 交互结果: {len(analyzer.results['interaction_results'])} 个")
        print(f"  📡 API发现: {len(analyzer.results['api_discoveries'])} 个")
        print(f"  ❌ 错误数量: {len(analyzer.results['errors'])}")
        
        # 显示发现的车型
        if analyzer.results['discovered_models']:
            print("\n🚗 发现的车型:")
            for model in analyzer.results['discovered_models']:
                print(f"    - {model['name']}")
        
        # 显示API发现
        if analyzer.results['api_discoveries']:
            print("\n📡 API发现:")
            for discovery in analyzer.results['api_discoveries']:
                if discovery['has_configurator']:
                    print(f"    - {discovery['model_name']}: 配置器页面 (API调用: {len(discovery['api_calls_detected'])})")
    
    else:
        print("❌ 交互式分析失败")

if __name__ == "__main__":
    main()
